<?php

/**
 * 客户端相关数据 Model
 */
class clientModel
{

    /**
     * 服务端数据版本
     * @var string 
     */
    private $sdv = '1.8.0';

    /**
     * 基类
     * @var object
     */
    private $base;

    /**
     * Mysql 连接
     * @var resources
     */
    private $db;

    /**
     * Redis 连接
     * @var resources
     */
    private $redis;

    public function __construct(& $base)
    {
        $this->base = $base;
        $this->db = & $this->base->db;
        $this->redis = & $this->base->redis;
    }

    /**
     * 客户端初始化
     * @param string $dv
     * @return array
     */
    public function statusInit($dv)
    {
        $result = array();
        // 最新数据版本号
        $result['sdv'] = $this->sdv;
        // 服务器状态
        $result['status'] = '1';
        // 闪屏图
        $result['init_pic'] = self::getadsinfo();
        // 用户信息
        $resClient = array();
        if($this->base->uid)
        {
            if($this->base->vn >= 1400 || ($this->base->vn >= 1200 && $this->base->projectId == 2))
            {
                $this->userEnergyChange($this->base->uid, 'upgrade');
            }
            $resClient = $this->getUserInfo($this->base->uid);
        }
        elseif($this->base->vn < '1100')
        {
            $resClient = $this->getVisitorInfo($this->base->vid);
        }
        $result['client'] = $resClient;
        // 单位为秒，提示周期是三天
        $result['alert_cycle'] = 3600 * 24 * 3;
        //是不是第一次注册
        $result['is_new'] = $this->base->is_new;
        $res = $this->redis->sismember(REDIS_PREFIX . 'clientNotReceivePush', $this->base->cid);
        $result['receive'] = $res ? 0 : 1;
        $maxNewsId = $this->base->vn >= 2000 ? 0 : $this->redis->ZREVRANGEBYSCORE(REDIS_PREFIX .'NewsList', '+inf', '-inf', array('limit' => array(0,1)));
        $result['maxNewsId'] = empty($maxNewsId) ? 0 : $maxNewsId[0];
        // 计算公式
        if($this->base->vn < 2000)
        {
            $result['formula'] = array(
                'calorie' => 'weight * (elapsedtime / 3600) * (30 / (elapsedtime / mileage * 400))',
                'donation' => 'km * 1',
            );
        }
        $result['token'] = $this->base->fromV1 ? $this->base->token : '';

        return $result;
    }

     /**
     * 获取后台设置的广告信息
     * @return array
     */
     public function getadsinfo()
     {
        $ads_default = array(
            'ads_desc' => '',
            'ads_is_click' => '0',
            'splasher_name' => 'joggers',
            'ads_is_show' => '0',
            'a_start_time' => '0',
            'a_end_time' => '0',
            'ads_name' => '',
            'ads_url' => '',
            'url_type' => 0,
            'daily_words' => '',
        );
        $packageChannel = common::request('packageChannel', 'G','');
        $packageChannel = trim($packageChannel);
        if(!empty($packageChannel))
        {
            $ads_info = $this->redis->hgetall(REDIS_PREFIX.'Splasher_'.$packageChannel);
            if(empty($ads_info) || $ads_info['ads_is_show'] == 0 || $ads_info['a_start_time'] > time() || $ads_info['a_end_time'] <= time())
            {
                $ads_info = array();
            }
        }
        if(empty($ads_info))
        {
            $ads_info = $this->redis->hgetall(REDIS_PREFIX.'Splasher_index');
            if(empty($ads_info) || $ads_info['ads_is_show'] == 0 || $ads_info['a_start_time'] > time() || $ads_info['a_end_time'] <= time())
            {
                $ads_info = array();
            }
        }
        if(!empty($ads_info))
        {
            $ads_info['url_type'] = 0;
            if(strpos($ads_info['ads_url'], 'joggers://') !== false)
            {
                if($this->base->vn >= 1900 || ($this->base->vn >= 1600 && $this->base->projectId == 2))
                {
                    $ads_info['url_type'] = 1;
                }
                else{
                    $ads_info['ads_is_click'] = 0;
                }
            }
            empty($packageChannel) && $packageChannel = 'index';
            $ads_info['splasher_name'] = md5($packageChannel. $ads_info['splasher_name']);
        }
        else{
            $ads_info = $ads_default;
        }
        $ads_info['pre_url'] = $this->base->load('qiniu')->getQNHost();
        return $ads_info;
     }
    /**
     * 以token为客户端唯一ID获取用户id
     * @param string $client
     * @return int
     */
    public function inUser($upLastInfo = FALSE)
    {
        $uid = NULL;
        //如果用户已经绑定，以绑定uid为先
        if ($this->base->token)
        {
            $tokenArr = explode('-', $this->base->token);
            $uid = $tokenArr[0];
            $time = isset($tokenArr[1]) ? intval($tokenArr[1]):'';
            $md5Str = isset($tokenArr[2]) ? trim($tokenArr[2]):'';
            $clientHash = isset($tokenArr[3]) ? trim($tokenArr[3]):'';

            if($clientHash && strlen($clientHash) == 32)
            {
                $uid = $this->base->alphaId->getNumber($uid);
            }

            $uid = intval($uid);

            $userInfo = $this->getUserInfo($uid);
            if(empty($userInfo))
                $uid = null;

            $tokenStr = $this->base->config['tokenStr'];
            if($this->base->vn < '1100' || $this->base->vn >= '9999') //处理1.0版本和web版请求
            {
                if(empty($uid))
                {
                    $this->base->token = '';
                    return false;
                }
            }
            elseif($this->base->fromV1)
            {
                $tokenArr = array($uid, time(), md5($uid.time().$tokenStr));
                $this->base->token = implode('-', $tokenArr);
            }
            elseif(md5($uid.$time.$tokenStr) != $md5Str)
            {
                $_ENV['error']->getErrors(302);
                exit;
            }
            if(!$uid)
            {
                $_ENV['error']->getErrors(101);
                exit;
            }
        }
        if($uid && $upLastInfo)
        {
            $data = array('lastcid' => $this->base->cid);
            $this->setUserInfo($uid, $data);
        }
        
        return $uid;
    }
    /**
     * 以Client为客户端唯一ID获取设备ID
     * @param string $client
     * @return int
     */
    public function inClient()
    {
        $cid = $this->getCid($this->base->client);
        if(!$cid)
        {
            $data = array(
                    'client' => $this->base->client,
                    'client_type' => $this->base->projectId,
                    'first_visit' => $this->base->time,
                    'last_visit' => $this->base->time,
                    'channel' => common::request('packageChannel','G',''),
                    'lastChannel' => common::request('packageChannel','G',''),
                    'version' => $this->base->vn
            );
            $cid = $this->insertClientInfo($data);
        }
        $this->base->cid = $cid;
        return $cid;
    }
    public function getCid($client)
    {
        $cid = $this->redis->hget(REDIS_PREFIX.'ClientCid', $client);
        if(!$cid)
        {
            $cid = $this->db->getOne("select cid from r_client where client = '{$client}'");
            $cid > 0 && $this->redis->hset(REDIS_PREFIX.'ClientCid', $client, $cid);
        }
        $cid = intval($cid);
        return $cid;
    }
    /**
     * 以Client为客户端唯一ID获取游客ID
     * @param string $client
     * @return int
     */
    public function inVisitor()
    {
        $vid = $this->getVid($this->base->client);
        if (!$vid)
        {
            $cid = $this->base->cid;
            $visitor = array(
                'addtime' => $this->base->time,
                'nickname' => $this->base->config['USER_PRE'],
                'cid' => $cid,
                'height' => 170,
                'weight' => 60,
                'age'    => 18,
                'type'   => $this->base->projectId,
                'version'=> $this->base->vn
            );
            if($this->base->vn < '1100')
            {
                $max_uid = $this->base->db->getone("select max(old_uid) from r_visitor");
                $max_uid = $max_uid >=80000 ? $max_uid +1 : 80000;
                $visitor['old_uid'] = $max_uid;
                $visitor['nickname'] .= str_pad($cid, 6, '0', STR_PAD_LEFT);
            }
            $vid = $this->insertVisitor($visitor);
            $this->base->is_new = 1;
        }
        $this->base->vid = $vid;
        return $vid;
    }
    /**
     * 通过Client获取游客 vid
     * @param string $client
     * @return int
     */
    public function getVid($client)
    {
        $vid = $this->redis->hget(REDIS_PREFIX . 'ClientIdVid', $client);
        if(!$vid && $this->base->cid)
        {
            $vid = $this->db->getOne("select vid from r_visitor where cid = '{$this->base->cid}'");
            $vid > 0 && $this->setVid($client, $vid);
        }
        return $vid;
    }

    /**
     * 设置Client对应的vid
     * @param string $client
     * @param int $vid
     * @return boolean
     */
    public function setVid($client, $vid)
    {
        return $this->redis->hset(REDIS_PREFIX . 'ClientIdVid', $client, $vid) !== FALSE;
    }

    /**
     * 添加设备基本信息
     * @param array $data
     * @return int
     */
    public function insertClientInfo(array $data)
    {
        $cid = $this->base->db->insertRowTable('r_client', $data);
        $cid > 0 && $this->redis->hset(REDIS_PREFIX . 'ClientCid', $this->base->client, $cid);
        return $this->redis->hget(REDIS_PREFIX . 'ClientCid', $this->base->client);
    }

    /**
     * 添加一条游客记录
     * @param array $data
     * @return vid
     */
    public function insertVisitor(array $data)
    {
        $vid = $this->base->db->insertRowTable('r_visitor', $data);
        if ($vid)
        {
            $this->setVid($this->base->client, $vid);
        }

        return $vid;
    }
    /**
     * 通过设备编号更新客户端信息
     * @param int $cid
     * @param array $data
     * @return boolean
     */
    public function setClientInfo($cid, array $data)
    {
        $data['cid'] = $cid;
        return $this->base->db->updateRowTable('r_client', $data);
    }
    /**
     * 设备编号获取设备信息
     * @param int $cid
     * @return array()
     */
    public function getClientInfo($cid)
    {
        $data = $this->base->db->getRow("select client, client_type from r_client where cid ='{$cid}'");
        return $data;
    }
    /**
     * 获取指定用户ID的信息
     * @param int $uid
     * @return array
     */
    public function getUserInfo($uid)
    {
        if(empty($uid))
        {
            return NULL;
        }
        $userInfo = array();
        if (is_array($uid))
        {
            foreach ($uid as $k => $v)
            {
                $userInfo[$v] = $this->getUserInfo($v);
            }
            /*
            $rm = $this->redis->multi();
            $result = array();
            foreach ($uid as $k => $v)
            {
                $rm->hgetall(REDIS_PREFIX . 'UserInfo_' . $v);
                $uid = $this->db->getone("select uid from r_user where uid = '{$v}'");
                if($uid)
                {
                    $result[] = $this->redis->hgetall(REDIS_PREFIX . 'UserInfo_' . $uid);
                }
                else
                {
                    $result[] = $this->db->getRow("select *, old_uid as uid from r_visitor where old_uid = '{$v}'");
                }
            }
            $result = $rm->exec();
            foreach ($result as $k => $v)
            {
                $userInfo[$v['uid']] = $result[$k];
            }
            */
        }
        else
        {
            try {
                $userInfo = $this->redis->hgetall(REDIS_PREFIX . 'UserInfo_' . $uid);
            }catch (Exception $e){
                $userInfo = array();
            }
            
            if (!$userInfo || (($this->base->vn>= 1400 || ($this->base->vn >= 1200 && $this->base->projectId == 2)) && !isset($userInfo['birth_day'])))
            {
                //$userInfo = $this->db->getRowTable('r_user', array(), "uid={$uid}");
                $userInfo = $this->db->getRow("select * from r_user left join r_user_ext on r_user_ext.uid = r_user.uid where r_user.uid={$uid} limit 1");
                if ($userInfo)
                {
                    $userInfo['age'] = date("Y") - $userInfo['age'];

                    unset($userInfo['lastcid'], $userInfo['sid'], $userInfo['key']);
                    // $userInfo['level'] = common::getLevel($userInfo['total_mileage']);
                    $this->setUserInfo($uid, $userInfo);
                    $birthday = $userInfo['birthday'];
                    $birthday = explode('-', $birthday);
                    $userInfo['birth_year'] = isset($birthday[0]) ? $birthday[0] : '1996';
                    $userInfo['birth_month'] = isset($birthday[1]) ? $birthday[1] : '1';
                    $userInfo['birth_day'] = isset($birthday[2]) ? $birthday[2] : '1';

                    if(!isset($userInfo['im_token']) || empty($userInfo['im_token']))
                    {
                        $userInfo['im_token'] = $this->initUserImToken($uid);
                    } 
                }
            }
            if($userInfo)
            {
                $userInfo['nickname'] = stripcslashes($userInfo['nickname']);
                $userInfo['levelInfo'] = $this->getUserLevelInfo($uid);
                $userInfo['latestRunRecord'] = $this->getLatestRunRecord($uid);
                $userInfo['max_elapsedtime'] = intval($userInfo['max_elapsedtime']);
                $userInfo['qq'] = empty($userInfo['qq']) ? 0 : 1;
                $userInfo['sina'] = empty($userInfo['sina']) ? 0 : 1;
                $userInfo['weixin'] = empty($userInfo['weixin']) ? 0 : 1;
                $userInfo['renren'] = empty($userInfo['renren']) ? 0 : 1;
                $userInfo['sync_run_mood_post'] = isset($userInfo['sync_run_mood_post']) ? (int)$userInfo['sync_run_mood_post'] : 1;

                if(!isset($userInfo['im_token']) || empty($userInfo['im_token']))
                {
                     $userInfo['im_token'] = $this->initUserImToken($uid);
                    
                } 
                
            }
            else
            {

                $userInfo = array();
            }
        }
        return $userInfo;
    }


    /**
     * 记录日志
     * @param  [type] $fileName [description]
     * @param  [type] $content  [description]
     * @return [type]           [description]
     */
    private function loginfo($content, $fileName = 'log', $folder = 'user'){
        //文件所处目录
        $path = $this->base->config['log-dir'] . $folder . "/";
        //查看文件目录是否存在,不存在创建
        !file_exists($path) && mkdir($path);
        //文件名称及类型
        $logName = $fileName.'.txt';
        //写入方式打开，将文件指针指向文件末尾。如果文件不存在则尝试创建之。
        $fp = fopen($path.$logName, "a");
        //文件内容前缀
        $log_prefix = '---start---'.date('Y-m-d H:i:s')."---\n";
        //文件内容后缀
        $log_suffix = '---end---'.date('Y-m-d H:i:s')."---\n";
        //写入内容
        fwrite($fp, $log_prefix . $content . "\n" . $log_suffix);
        //写入换行
        fwrite($fp, "\n");
        //关闭
        fclose($fp);
    }

    /**
     * 加载用户的im_token 当第一次redis中userinfo中没有im_token字段信息时
     * @param  [type] $userInfo [description]
     * @return [type]           [description]
     */
    private function initUserImToken($uid){

        $im_token = "";
        $uid = intval($uid);
        $rst = $this->db->getRowTable('r_user', array('im_token','nickname','header'), "uid={$uid}");
        $im_token = $rst['im_token'];

        //$this->loginfo("111111========".var_export($rst,true));
        if(empty($im_token)){

            $nickname = isset($rst['nickname']) ? $rst['nickname'] : "";
            $header = isset($rst['header']) ? $rst['header'] : "";

            //$this->loginfo("4444========".var_export($nickname,true)."----".var_export($header,true));

            $im_token = $this->getImToken($uid, $nickname, $header);
            //$this->loginfo("22222========".var_export($im_token,true));
            $rst = $this->db->updateRowTable('r_user', array('uid'=>$uid,'im_token'=>$im_token));

            //$this->loginfo("333333========".var_export($rst,true));
        }
        return $im_token;
    }


    /**
     * 新用户获取im_token 
     * @param  [type] $uid    [description]
     * @param  [type] $name   [description]
     * @param  [type] $header [description]
     * @return [type]         [description]
     */
    private function getImToken($uid, $name, $header){
        $rst = $this->db->getRowTable('r_user', array('im_token','nickname','header'), "uid={$uid}");
        //当用户对应的im_token为空时,获取新的im_token;如果不为空,判断name和header是否不同,如果不同,更新用户信息
        //$this->loginfo("5555========".var_export($rst,true));
        if(empty($rst['im_token'])){
            $nickname = isset($rst['nickname']) ? $rst['nickname'] : "";
            $header = isset($rst['header']) ? $rst['header'] : "";

            //$this->loginfo("6666========".var_export($uid,true)."------".var_export($nickname,true)."----".var_export($header,true));
            $result = $this->base->load('message')->getToken($uid,$name,$header);

            //$this->loginfo("result ========".var_export($result,true));
            //$this->loginfo("token result========".var_export($result,true));

            $im_token = "";
            if(isset($result['code']) && 200 == $result['code']){
                $im_token = $result['token'];
                //$this->loginfo("7777========".var_export($im_token,true));
                $rst = $this->db->updateRowTable('r_user', array('uid'=>$uid,'im_token'=>$im_token));
            }
            
            return $im_token;
        }else{
            //$this->loginfo("999999========".var_export($name,true) . "=" . $rst['nickname']. ";" . var_export($header,true) . "=" . $rst['header']);
            if($name != $rst['nickname'] || $header != $rst['header']){
                $this->base->load('message')->userRefresh($uid, $name, $header);
            }
            //$this->loginfo("000000000========".var_export($rst['im_token'],true) );
            return $rst['im_token'];
        }
    }

    /**
     * 设置指定设备ID的用户信息
     * @param int $uid
     * @param array $data
     * @return boolean
     */
    public function setUserInfo($uid, array $data)
    {
        $result = FALSE;

        $data['uid'] = $uid;
        if(isset($data['age']))
        {
            $data['age'] = $data['age'] <=100 ? date("Y") - $data['age'] : $data['age'];
            !isset($data['birthday']) && $data['birthday'] = $data['age'] .'-1-1';
        }

        //$this->loginfo(var_dump($data));

        //新用户获取im_token
        // if(isset($data['nickname']) && !empty($data['nickname']) && isset($data['header']) && !empty($data['header'])){
        //     $nickname = isset($data['nickname']) ? $data['nickname'] : "";
        //     $header = isset($data['header']) ? $data['header'] : "";
        //     $data['im_token'] = $this->getImToken($uid, $nickname, $header);
        // }
        

        if ($this->base->load('user')->update($data))
        {
            unset($data['rank']);
            isset($data['age']) && $data['age'] = date("Y") - $data['age'];
            if(($this->base->vn>= 1400 || ($this->base->vn >= 1200 && $this->base->projectId == 2)) && isset($data['birthday']))
            {
                $birthday = $data['birthday'];
                $birthday = explode('-', $birthday);
                $data['birth_year'] = @$birthday[0] ? $birthday[0] : 1996;
                $data['birth_month'] = @$birthday[1] ? $birthday[1]:1;
                $data['birth_day'] = @$birthday[2] ? $birthday[2]:1;
            }
            $result = $this->redis->hmset(REDIS_PREFIX . 'UserInfo_' . $uid, $data);
            if ($result && $uid == $this->base->uid)
            {
                foreach ($data as $k => $v)
                {
                    $this->base->userInfo[$k] = $v;
                }
            }
        }
        return $result;
    }

    

    /**
     * 获取指定游客ID的信息
     * @param int $vid
     * @return array
     */
    public function getVisitorInfo($vid)
    {
        $VisitorInfo = array();
        $VisitorInfo = $this->redis->hgetall(REDIS_PREFIX . 'VisitorInfo_' . $vid);
        if (!$VisitorInfo)
        {
            $VisitorInfo = $this->db->getRowTable('r_visitor', array(), "vid={$vid}");
            if ($VisitorInfo)
            {
                unset($VisitorInfo['lastcid'], $VisitorInfo['sid'], $VisitorInfo['key'], $VisitorInfo['vid'], $VisitorInfo['weibo']);
                $this->saveVisitorInfo($vid, $VisitorInfo);
                $VisitorInfo['age'] = date("Y") - $VisitorInfo['age'];
            }
        }
        if($VisitorInfo)
        {
            $VisitorInfo['nickname'] = isset($VisitorInfo['old_uid']) && $VisitorInfo['old_uid'] > 1 ? $VisitorInfo['nickname'] : 'Runner';
            $VisitorInfo['qq'] = 0;
            $VisitorInfo['sina'] = 0;
            $VisitorInfo['weixin'] = 0;
            $VisitorInfo['renren'] = 0;
        }
        return $VisitorInfo;
    }
    /**
     * 设置指定游客ID的用户信息
     * @param int $vid
     * @param array $data
     * @return boolean
     */
    public function saveVisitorInfo($vid, array $data)
    {
        $result = FALSE;

        $data['vid'] = $vid;
        $data['age'] = (isset($data['age']) && $data['age'] > 0) ? date("Y") - $data['age'] : 1996;
        if ($this->db->updateRowTable('r_visitor', $data))
        {
            unset($data['rank'], $data['addtime']);
            $data['age'] = date("Y") - $data['age'];
            $result = $this->redis->hmset(REDIS_PREFIX . 'VisitorInfo_' . $vid, $data);
        }
        return $result;
    }
    /**
     * 获取用户跑步等级信息
     * @param int $uid
     * @param boolen $update 是否更新
     * @return array()
     */
    public function getUserLevelInfo($uid, $update = false)
    {
        $result = $this->redis->hgetall(REDIS_PREFIX . 'UserLevelInfo_'.$uid);
        if(!$result || $update)
        {
            $result = array();
            $runInfo = $this->db->getRow("select level, total_mileage from r_user where uid = '{$uid}'");
            if($runInfo)
            {
                $level =common::getLevel($runInfo['total_mileage']);
                $mileage = $runInfo['total_mileage'];
                $levelInfo = common::$runLevel[$level];

                $result['level'] = $level;
                $result['title'] = $levelInfo['title'];
                $result['nextLevelValue'] = $levelInfo['min'] + $levelInfo['spacing'];
                $result['upgrade_rate'] = round(($mileage-$levelInfo['min'])/$levelInfo['spacing'], 2);
                $result['upgrade_rate'] > 1 && $result['upgrade_rate'] = 0.99;
                $this->redis->hmset(REDIS_PREFIX.'UserLevelInfo_'.$uid, $result);
            }
        }
        $nextLevel = $result['level']+1;
        $result['nextLevel'] = $nextLevel;
        $runLevel = common::$runLevel;
        $result['nextTitle'] = isset($runLevel[$nextLevel]) ? $runLevel[$nextLevel]['title'] : '';
        return $result;
    }
    /**
     * 更新最近跑步记录
     * @param int $uid
     * @param array $runData 最新跑步数据
     * @param boolen $update 是否更新
     * @return array()
     */
    public function getLatestRunRecord($uid, $runData = array(), $update = false)
    {
        $result = $this->redis->hgetall(REDIS_PREFIX . 'latestRun_'.$uid);
        if(!$result || $update || !empty($runData))
        {
            $result = array();
            if(empty($runData) || @empty($runData['mileage']) || @empty($runData['elapsedtime']) || @empty($runData['city']) || @empty($runData['calorie']) || @empty($runData['updatetime']))
            {
                $runData = array();
                $runData = $this->db->getRow("select mileage, elapsedtime, city, calorie,updatetime from r_data where uid = '{$uid}' and is_delete = 0 and overSpeed = 0 order by updatetime DESC limit 1");
            }
            if($runData)
            {
                //$latestRunWords = $this->base->config['latestRunWords'];
                $city = $runData['city'] == '未知' ? '一个谁也不知道的地方': $runData['city'];
                $elapsedtime = $runData['elapsedtime'];
                //$timediff = common::timediff(time() - $runData['updatetime'],'run');
                //$mileage = $runData['mileage']. 'km';
                //$result['run_time'] = $runData['updatetime'];
                //$result['description'] = sprintf($latestRunWords, $timediff, $mileage);
                $result['run_time'] = $runData['updatetime'];
                $result['description'] = $runData['mileage'];
            }
            else
            {
                $result['run_time'] = $this->db->getOne("select addtime from r_user where uid = '{$uid}'");
                $result['description'] = '活动一下筋骨，做好热身就去跑';
            }
            $this->redis->hmset(REDIS_PREFIX . 'latestRun_' .$uid, $result);
        }
        return $result;
    }
     /**
     * 处理用户头像上传
     * @param string $inputName
     * @return string
     */
    public function uploadUserHeader($inputName)
    {
        $result = FALSE;

        if (!empty($_FILES[$inputName]) && $_FILES[$inputName]['error'] == 0 && in_array($_FILES[$inputName]['type'], array('image/png', 'image/gif', 'image/jpeg')))
        {
            $day = date('Ymd');
            $fix = str_replace(array('image/', 'jpeg'), array('', 'jpg'), $_FILES[$inputName]['type']);
            $upPath = FILE . '../web/static/u/' . $day . '/';
            $fileName = md5($_FILES[$inputName]['name'] . microtime(TRUE)) . '.' . $fix;
            $upFileName = $upPath . $fileName;

            !file_exists($upPath) && mkdir($upPath);

            if (move_uploaded_file($_FILES[$inputName]['tmp_name'], $upFileName))
            {
                // 缩略图
                require FILE . 'lib/image.class.php';
                !file_exists($upPath . 'thumb') && mkdir($upPath . 'thumb');
                $rel = Image::thumb($upPath . $fileName, $upPath.'thumb/'.$fileName, '', 180, 180);
                $result = 'http://'. $this->base->config['host'] . '/static/u/' . $day;;
                $result .= $rel ? '/thumb/' : '/';
                $result .= $fileName;
            }
        }
        return $result;
    }
    /**
     * 保存IOS设备 消息推送 token
     * @param int $cid
     * @param string $push_token
     * @return string
     */
    public function saveIOSPushToken($cid, $push_token)
    {
        $result = 0;

        if (!empty($cid) && !empty($push_token))
        {
            $data['push_token'] = $push_token;
            $data['pushFailCount'] = 0;
            $data['isPushVaild'] = 1;
            return $this->setClientInfo($cid, $data);
        }
        return $result;
    }
    /**
     * 记录用户正能量变动历史
     * @param int $uid        用户id
     * @param string $type    变动类型
     * @param float $value    变动相关值 如点赞时的点赞用户id,跑步时的跑步记录id
     * @return int    energy_add  正能量变动值，增加时为正数，减少时为负数
     */
    public function userEnergyChange($uid =0, $type='', $value=0)
    {
        $energy_add = 0;
        if(!empty($uid) && !empty($type))
        {
            $EnengySet = common::$energySet;

            $weekarray=array("日","一","二","三","四","五","六");
            if(!isset($EnengySet[$type]))
            {
                return $energy_add;
            }
            $setting = $EnengySet[$type];
            $add_time = time();
            $date = date("Y-m-d", $add_time);
            $week = date("w", $add_time);
            $week = '星期'.$weekarray[$week];
            $news_id = null;
            $target_uid = 0;

            $userInfo = $this->getUserInfo($uid);
            $total_energy = $userInfo['total_energy'];
            switch ($type)
            {
                case 'new':
                    if(!$this->redis->hexists(REDIS_PREFIX.'userNewUpg', $uid))
                    {
                        $value = '';
                        $energy_add = $setting['energy'];
                        $description = $setting['description'];
                    }
                    break;
                case 'upgrade':
                    if(!$this->redis->hexists(REDIS_PREFIX.'userNewUpg', $uid))
                    {
                        $value = '';
                        $energy_add = $setting['energy'];
                        $description = $setting['description'];
                    }
                    break;
                case 'comment':
                    $redisKey = REDIS_PREFIX.'userComment_'.$uid.'_'.date("Ymd");
                    $times = $this->redis->get($redisKey) ? $this->redis->get($redisKey) : 0;
                    if($times < $setting['limit'])
                    {
                        $energy_add = $setting['energy'];
                        $description = $setting['description'];
                        $times +=1;
                    }
                    break;
                case 'run':
                    $redisKey = REDIS_PREFIX.'userRun_'.$uid.'_'.date("Ymd");
                    $times = $this->redis->get($redisKey) ? $this->redis->get($redisKey) : 0;
                    if($times < $setting['limit'])
                    {
                        $energy_add = intval($value) * $setting['energy'];
                        $description = sprintf($setting['description'], $value);
                        $times +=1;
                    }
                    break;
                case 'target':
                    $redisKey = REDIS_PREFIX.'userRunTarget_'.$uid.'_'.date("Ymd");
                    $times = $this->redis->get($redisKey) ? $this->redis->get($redisKey) : 0;
                    if($times < $setting['limit'])
                    {
                        $energy_add = intval($value)*$EnengySet['run']['energy'] +$setting['energy'];
                        $description = sprintf($setting['description'], $value);
                        $times +=1;
                    }
                    break;
                case 'share':
                    $redisKey = REDIS_PREFIX.'userRunShare_'.$uid.'_'.date("Ymd");
                    $times = $this->redis->get($redisKey) ? $this->redis->get($redisKey) : 0;
                    if($times < $setting['limit'] && !$this->redis->sismember(REDIS_PREFIX.'userRunShare_'.$uid, $value))
                    {
                        $energy_add = $setting['energy'];
                        $description = $setting['description'];
                        $times +=1;
                    }
                    break;
                case 'post':
                    $redisKey = REDIS_PREFIX.'userPost_'.$uid.'_'.date("Ymd");
                    $times = $this->redis->get($redisKey) ? $this->redis->get($redisKey) : 0;
                    if($times < $setting['limit'] && !$this->redis->sismember(REDIS_PREFIX.'userPost_'.$uid, $value))
                    {
                        $energy_add = $setting['energy'];
                        $description = $setting['description'];
                        $times +=1;
                        $news_id = $value;
                    }
                    break;
                case 'pay':
                    if(!is_array($value)){
                        return false;
                    }
                    extract($value);//$target_uid,$news_id,$energy_add
                    $value = $news_id;
                    $description = $setting['description'];
                    break;
                case 'paid':
                    if(!is_array($value)){
                        return false;
                    }
                    extract($value);//$target_uid,$news_id,$energy_add
                    $value = $news_id;
                    $description = $setting['description'];
                    break;
                case 'createActivity':
                case 'joinActivity':
                case 'shareActivity':
                    //value=aid
                    $redisKey = REDIS_PREFIX."user{$type}_{$uid}_".date("Ymd");
                    $times = $this->redis->get($redisKey) ? $this->redis->get($redisKey) : 0;
                    if($times < $setting['limit'] && !$this->redis->sismember(REDIS_PREFIX."user{$type}_{$uid}", $value)){
                        $energy_add = $setting['energy'];
                        $description = $setting['description'];
                        $times++;
                        $aid = $value;
                    }
                    break;
                case 'paomeCreateClub':
                    $energy_add = -$setting['energy'];
                    $description = $setting['description'];
                    break;
                case 'paomePay':
                    if(!is_array($value)){
                        return false;
                    }
                    extract($value);    //$target_uid,$energy_add
                    $description = $setting['description'];
                    unset($value);    
                    break;
                case 'paomePaid':
                    if(!is_array($value)){
                        return false;
                    }
                    extract($value);    //$target_uid,$energy_add
                    unset($value);
                    $description = $setting['description'];
                    break;
                case 'careMonster':
                    $description = $setting['description'];
                    $energy_add = -$setting['energy'];
                    extract($value);    //$target_uid,$monster_id
                    $value = $monster_id;
                    break;
                case 'gameGift':
                    if(!is_array($value)){
                        return false;
                    }
                    extract($value);    //$energy_add
                    unset($value);
                    $description = $setting['description'];
                    break;
                default:
                    # code...
                    break;
            }
            
            if($energy_add > 0 || $type == 'pay' || $type == 'paomeCreateClub' || $type == 'paomePay' || $type == 'careMonster')
            {
                $total_energy += $energy_add;
                if($total_energy < 0){
                    return false;
                }
                $result = $this->setUserInfo($uid, array('total_energy' =>$total_energy));
                $insertArray = compact('uid','type','value','add_time','date','week','energy_add','description','news_id','target_uid','total_energy');
                $record_id = $this->db->insertRowTable('r_energy_record', $insertArray);
                if($result)
                {
                    $nextDay = date("Ymd",strtotime('tomorrow'));
                    $expire = strtotime($nextDay) - time();
                    switch ($type) {
                        case 'new':
                            $this->redis->hset(REDIS_PREFIX.'userNewUpg', $uid, $add_time);
                            break;
                        case 'upgrade':
                            $this->redis->hset(REDIS_PREFIX.'userNewUpg', $uid, $add_time);
                            break;
                        case 'comment':
                            $redisKey = REDIS_PREFIX.'userComment_'.$uid.'_'.date("Ymd");
                            $this->redis->set($redisKey, $times);
                            $this->redis->expire($redisKey, $expire);
                            break;
                        case 'run':
                            $redisKey = REDIS_PREFIX.'userRun_'.$uid.'_'.date("Ymd");
                            $this->redis->set($redisKey, $times);
                            $this->redis->expire($redisKey, $expire);
                            break;
                        case 'target':
                            $redisKey = REDIS_PREFIX.'userRunTarget_'.$uid.'_'.date("Ymd");
                            $this->redis->set($redisKey, $times);
                            $this->redis->expire($redisKey, $expire);
                            break;
                        case 'share':
                            $redisKey = REDIS_PREFIX.'userRunShare_'.$uid.'_'.date("Ymd");
                            $this->redis->set($redisKey, $times);
                            $this->redis->expire($redisKey, $expire);
                            $this->redis->sadd(REDIS_PREFIX.'userRunShare_'.$uid, $value);
                            break;
                        case 'post':
                            $redisKey = REDIS_PREFIX.'userPost_'.$uid.'_'.date("Ymd");
                            $this->redis->set($redisKey, $times);
                            $this->redis->expire($redisKey, $expire);
                            $this->redis->sadd(REDIS_PREFIX.'userPost_'.$uid, $value);
                            $this->addPostEnergy($news_id,$energy_add,true);
                            break;
                        case 'pay':
                            $redisKey = REDIS_PREFIX.'PostPayUserList_'.$news_id;
                            $this->redis->sadd($redisKey,$uid);
                            break;
                        case 'paid':
                            $this->addPostEnergy($news_id,$energy_add);
                            break;
                        case 'createActivity':
                        case 'joinActivity':
                        case 'shareActivity':
                            $redisKey = REDIS_PREFIX."user{$type}_{$uid}_".date("Ymd");
                            $this->redis->set($redisKey, $times);
                            $this->redis->expire($redisKey, $expire);
                            $this->redis->sadd(REDIS_PREFIX."user{$type}_{$uid}", $value);
                            break;
                        default:
                            # code...
                            break;
                    }
                }
            }
        }
        return $energy_add;
    }
     /**
     * 为别人点赞
     * @param int $light_uid 点赞操作用户id
     * @param int $uid        被点赞用户id
     */
    public function thumbsUserUp($light_uid, $uid )
    {
        $lights = $this->redis->hget(REDIS_PREFIX . 'UserInfo_'.$uid, 'lights');
        empty($lights) && $lights = 0;
        empty($total_energy) && $total_energy = 0;

        $lightsAdd = $lights +1;
        if($this->setUserInfo($uid, array('lights' => $lightsAdd)))
        {
            $lights = $lightsAdd;
            $this->redis->hset(REDIS_PREFIX . 'userCenterLight_' . $uid, $light_uid, time());
            $recordArray = array('uid' =>$uid, 'light_uid' => $light_uid, 'add_time' => time());
            $this->db->insertRowTable('r_UCLightsRecord', $recordArray);
        }
        return array('thumbs' =>$lights);
    }
    /**
     * 点赞列表
     * @param int $uid        被点赞用户id
     * @param int $point 起始点 record_id
     * @param string $direc 数据加载方式
     * @param int $offset 返回数据条数
     * @return array
     */
    public function getThumbsList($uid, $point = 0, $direc ='next', $offset = 20)
    {
        $result = array();
        if($uid)
        {
            $point = intval($point);
            $sql = "select record_id, light_uid, add_time from r_UCLightsRecord where uid = {$uid} ";
            if(empty($point))
            {
                $sql .= "order by record_id DESC limit {$offset}";
            }
            else
            {
                if($direc == 'next')
                {
                    $sql .= "and record_id < {$point} order by record_id DESC limit {$offset}";
                }
                else
                {
                    $sql .="and record_id > {$point} order by record_id ASC limit {$offset}";
                }
            }
            $users = $this->db->getAll($sql);
            if($users)
            {
                $point >0 && $direc != 'next' && krsort($users);
                foreach ($users as $v) {
                    $user = $v['light_uid'];
                    $userInfo = $this->getUserInfo($user);
                    if($userInfo)
                    {
                        $result[] = array(  'uid' => $user,
                                            'header'=>$userInfo['header'],
                                            'nickname'=>$userInfo['nickname'],
                                            'gender'=>$userInfo['gender'],
                                            'levelInfo'=>$this->getUserLevelInfo($user),
                                            'total_mileage'=>$userInfo['total_mileage'],
                                            'total_energy'=>$userInfo['total_energy'],
                                            'total_rate'=>$userInfo['total_rate'],
                                            'add_time'=>$v['add_time'],
                                            'record_id'=>$v['record_id']
                            );
                        unset($userInfo);
                    }
                }
            }
        }
        return $result;
    }
    /**
     * 正能量变动记录
     * @param int $uid        用户id
     * @param int $point 起始点 record_id
     * @param string $direc 数据加载方式
     * @param int $offset 返回数据条数
     * @return array
     */
    public function getenergyRecord($uid, $point = 0, $direc ='next', $offset = 20)
    {
        $records = array();
        if($uid)
        {
            $point = intval($point);
            $sql = "select record_id, date, week, energy_add,description from r_energy_record where uid = {$uid} ";
            if(empty($point))
            {
                $sql .= "order by record_id DESC limit {$offset}";
            }
            else
            {
                if($direc == 'next')
                {
                    $sql .= "and record_id < {$point} order by record_id DESC limit {$offset}";
                }
                else
                {
                    $sql .="and record_id > {$point} order by record_id ASC limit {$offset}";
                }
            }
            $records = $this->db->getAll($sql);
        }
        return $records;
    }
    /**
     *  获取预设背景图信息
     * @return array REDIS_PREFIX.''
     */
    public function getUserBgInfo($background_id)
    {
        $bgInfo = $this->redis->hgetall(REDIS_PREFIX . 'UserBg_' . $background_id);
        if (!$bgInfo)
        {
            $bgInfo = $this->db->getRowTable('r_bg_list', array(), "background_id={$background_id} and is_show =1");
        }
        return $bgInfo;
    }
    /**
     *  获取个人中心背景图列表
     * @return array
     */
    public function getUCenterBgList()
    {
        $result = array();
        $bgs = $this->redis->zrevrange(REDIS_PREFIX . 'SortBackGround', 0, -1);
        if($bgs)
        {
            foreach ($bgs as $background_id) {
                $bgInfo = $this->getUserBgInfo($background_id);
                $bgInfo && $result[] = $bgInfo;
            }
        }
        return $result;
    }
    /**
     *  设置个人中心背景图
     * @param int $uid
     * @param string background_url
     * @return array
     */
    public function setMycenterBg($uid, $background_url)
    {
        if(!empty($uid) && !empty($background_url))
        {
            $this->setUserInfo($uid, array('background' => $background_url));
        }
        $background = $this->redis->hget(REDIS_PREFIX . 'UserInfo_' . $uid, 'background');
        $result = array('background' => $background);
        return $result;
    }
    /**
     *  分享跑步记录成功获取正能量
     * @param int $uid
     * @param int order
     * @return
     */
    public function shareRunGetEnergy($uid, $order)
    {
        if($uid && $order)
        {
            $this->userEnergyChange($uid, 'share', $order);
        }
        else
        {
            $_ENV['error']->getErrors(101);
            exit;
        }
        return $this->redis->hget(REDIS_PREFIX .'UserInfo_'.$uid, 'total_energy');
    }
    /**
     *  用户跑步等级列表
     * @param int $uid
     * @return array
     */
    public function getRunLevelList($uid)
    {
        $result = array();
        if($uid)
        {
            $result = $this->db->getAll("select level, description, add_time from r_runLevelRecord where uid = {$uid} order by record_id DESC");
            if($result)
            {
                $weekarray=array("日","一","二","三","四","五","六");
                foreach ($result as & $value) {
                    $value['date'] = date("Y-m-d", $value['add_time']);
                    $week = date("w", $value['add_time']);
                    $value['week'] = '星期'.$weekarray[$week];
                    unset($value['add_time']);
                }
            }
        }
        return $result;
    }
    /**
     *  是否接收推送消息
     * @param string $cid
     * @param int $receive
     * @return
     */
    public function setPushMes($cid, $receive)
    {
        $cid = intval($cid);
        $isAcceptPush = $receive ? 1 : 0;

        $redisKey = REDIS_PREFIX . 'clientNotReceivePush';
        // 设备当前是否接收推送
        $result = $this->redis->sismember($redisKey, $cid) ? 0 : 1;

        if($result == $isAcceptPush) 
        {
            return $result;
        }

        if($cid > 0)
        {
            $updateData = compact('cid', 'isAcceptPush');
            if($this->db->updateRowTable('r_client', $updateData))
            {
                $result = $isAcceptPush;
                if($isAcceptPush == 1)
                {
                    $this->redis->srem($redisKey, $cid);
                }
                else
                {
                    $this->redis->sadd($redisKey, $cid);
                }
            }
        }
        
        return $result;
    }
    /**
     *  获取当月（周）用户跑步数据
     * @param int $uid
     * @param string $type  ('week', 'month')
     * @param boolen $update 是否更新
     * @return array()
     */
    public function getUserFrRunData($uid, $type,$update = false)
    {
        $redisKey = $type == 'week'?REDIS_PREFIX.'UserRunData_'.$type.date("W").'_'.$uid:REDIS_PREFIX.'UserRunData_'.$type.date("n").'_'.$uid;
        $result = $this->redis->hgetall($redisKey);
        if(!$result || $update)
        {
            $time = $type=='week' ? strtotime("next Monday") -7*86400:strtotime(date("Y").'-'.date("m").'-1');
            $result = $this->db->getRow("select count(*) as total_rate, sum(mileage) as total_mileage from r_data where uid={$uid} and updatetime>={$time} and is_delete = 0 and overSpeed = 0");
            empty($result['total_mileage']) && $result['total_mileage']=0;
            $result['total_mileage'] = round($result['total_mileage'], 2);
            $this->redis->hmset($redisKey, $result);
            // 设置有效期
            $expireTime = $type == 'week' ? strtotime("next Monday"):strtotime(date("Y").'-'.(date("m")+1).'-1');
            $expireTime -= time();
            $this->redis->expire($redisKey, $expireTime);
        }
        return $result;
    }
    
    
    
    
    
    
    
    
    
    /**
     * 根据多个uid获取多个cid
     * @param unknown $data uid 集合(array('uid','uid'))
     * @return multitype:multitype: array(array("type"=>"1","token"=>array('clientId','clientId')),array("type"=>"2","token"=>array("push_token","push_token")))
     */
    public function getMultiClientId($data)
    {
        $androidClientData = array();
        $iosClientData = array();
        if ($data) {
            foreach ($data as $val){
                $cid = $this->getClientId($val);
                if(!$cid)
                    continue;
                $ctype = $this->getClientTypeByCid($cid);
                $ctoken = $this->getClientOrPushTokenByCid($ctype,$cid);
                if($ctype == 1) array_push($androidClientData,$ctoken);
                if($ctype == 2) array_push($iosClientData,$ctoken);
            }
        }

        return array(array('type'=>'1','token'=>$androidClientData),array('type'=>'2','token'=>$iosClientData));
    }
    
    
    /**
     * 通过uid获取cid
     * @param unknown $uid 用户ID
     * @return Ambigous <string, number, unknown, NULL>
     */
    private function getClientId($uid){
        $userInfo = $this->getUserInfoByRefactor($uid);
        $lastcId = isset($userInfo['lastcid']) ? $userInfo['lastcid'] : "";
        $cid = isset($userInfo['cid']) ? $userInfo['cid'] : "";
        return !empty($lastcId) ? $lastcId : !empty($cid) ? $cid : "";
    }
    
    /**
     * 根据uid获取用户信息
     * @param unknown $uid
     */
    private function getUserInfoByRefactor($uid){
        return $this->redis->hgetall(REDIS_PREFIX . 'UserInfo_' . $uid);
    }
    
    /**
     * 根据cid获取设备类型(1:android,2:ios)
     * @param unknown $cid
     */
    private function getClientTypeByCid($cid){
        return $this->db->getOne("select client_type from r_client where cid = '{$cid}'");
    }
    
    public function getClientOrPushTokenByCid($type,$cid){
        if($type == 1) $sql = "select client from r_client where cid = '{$cid}'";
        if($type == 2) $sql = "select push_token from r_client where cid = '{$cid}'";
        return $this->db->getOne($sql);
    }

    /**
     * 获取用户数量
     * @return [type] [description]
     */
    public function getAllUserCount(){
        return $this->db->getOne("select count(*) as totalNum from r_user");
    }

    /**
     * 分段获取用户信息
     * @param  [type] $offset [description]
     * @param  [type] $rows   [description]
     * @return [type]         [description]
     */
    public function getAllUser($offset, $rows){
        return $this->db->getAll("select * from r_user limit " . $offset . "," . $rows);
    }

    /**
     * 通过用户ID获取用户对应的版本号
     * @param  [type] $uid [description]
     * @return [type]      [description]
     */
    public function getClientInfoByUid($uid){
        $clientInfo = $this->redis->hgetall(REDIS_PREFIX .'ClientInfo_'.$uid);
        if(empty($clientInfo)){
            $userInfo = $this->db->getRow("select * from r_user where uid = '{$uid}'");

            $cid = isset($userInfo['lastcid']) && !empty($userInfo['lastcid']) ? $userInfo['lastcid'] : isset($userInfo['cid']) && !empty($userInfo['cid']) ? $userInfo['cid'] : "";


            $clientInfo = $this->db->getRow("select * from r_client where cid = '{$cid}'");
            if(!empty($clientInfo)){
                $this->redis->hmset(REDIS_PREFIX . 'ClientInfo_' . $uid, $clientInfo);
            }
        }
        return $clientInfo;
    }

    /**
     * 通过cid获取版本号
     * @param $cid
     * @return int
     */
    public function getVersionByCid($cid){
        $versionInfo = $this->db->getRow("select version from r_client where cid = '{$cid}'");
        return intval($versionInfo['version']);

    }
    
    /*
     * 添加文章的正能量
     */
    public function addPostEnergy($news_id,$energy,$system=false){
        $bbs_mod = $this->base->load('bbs');
        $postInfo = $bbs_mod->getPostInfo($news_id);
        
        if(!$postInfo){
            return false;
        }
        
        $redisKey = REDIS_PREFIX. 'NewsInfo_'.$news_id;
        $this->redis->hincrby($redisKey,'energy',$energy);
        if(!$system){
            $this->redis->hincrby($redisKey,'energy_pay_count',1);
        }
        
        $postInfo = $bbs_mod->getPostInfo($news_id);
        $energy_pay_count = $postInfo['energy_pay_count'];
        $this->base->db->update("update r_news set energy=energy+{$energy}, energy_pay_count=energy_pay_count+1 where news_id={$news_id}");
    }
    
    /*
     * 文章是否已被打赏
     */
    public function isPostPaidBy($news_id,$uid){
        $redisKey = REDIS_PREFIX.'PostPayUserList_'.$news_id;
        return $this->redis->exists($redisKey) && $this->redis->sismember($redisKey,$uid);
    }

    /*
     * 获得个人中心导航
     */
    public function getUserChannel(){
        $data = $this->redis->GET(REDIS_PREFIX.'userChannel');
        return json_decode($data,true);
    }
}
